<script setup lang="ts">
import { ref, computed, reactive, watch } from 'vue'
import { ElTable, ElTableColumn } from 'element-plus'
import TableColumn from './TableColumn.vue'

const props = defineProps({
  columns: {
    type: Array,
    default: () => [
      { title: '名字', dataIndex: 'name' },
      {
        title: 'a列',
        children: [
          { title: 'b列', dataIndex: 'b', sortable: true, showOverflowTooltip: true },
          { title: 'c列', dataIndex: 'c' }
        ]
      }
    ]
  },
  data: {
    type: Array,
    default: () => [
      { b: '1', c: '2' },
      { b: '3', c: '4' }
    ]
  },
  height: [Number, String],
  selection: {
    type: Boolean,
    default: false
  },
  transparent: {
    type: Boolean,
    default: false
  },
  autoScroll: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['selection-change'])

const slots = defineSlots()

const tableRef = ref()

const tableThArr: any = computed(() => props.columns)

const handleSelectionChange = (val) => {
  emit('selection-change', val)
}

const transparentStyle = reactive({
  '--el-table-bg-color': 'transparent',
  '--el-table-tr-bg-color': 'transparent',
  '--el-table-header-bg-color': 'rgb(255 255 255 / 0.05)',
  '--el-fill-color-light': 'rgb(255 255 255 / 0.05)',
  '--el-fill-color-lighter': 'rgb(255 255 255 / 0.02)',
  '--el-table-border': '1px solid transparent',
  '--el-table-border-color': 'transparent'
})
// 自动滚动
const scrollDelay = 1500
const cellHeight = 40
let intervalScroll = null
let srollable = ref(true)
// 表格数据
const tableData = computed(() => {
  if (props.autoScroll) {
    const headerDeep = count(props.columns)
    const headerHeight = cellHeight * headerDeep
    const bodyHeight = typeof props.height == 'string' ? 0 : props.height - headerHeight

    return cellHeight * props.data.length > bodyHeight ? props.data.concat(props.data) : props.data
  }

  return props.data
})
// 计算表头深度
function count(column, num = 0) {
  if (column?.length > 0) {
    return Math.max(
      ...column.map((item) => {
        if (item.children) return count(item.children, num + 1)
        else return num + 1
      })
    )
  }

  return num
}

const scroll = () => {
  let y = 0

  return () => {
    if (!srollable.value) return

    const length = props.data.length
    const top = (y % (length + 1)) * cellHeight

    tableRef.value?.scrollTo({
      left: 0,
      top,
      behavior: top == 0 ? 'instant' : 'smooth'
    })

    y++
  }
}

watch(
  () => props.autoScroll,
  (newVal) => {
    if (intervalScroll) clearInterval(intervalScroll)

    if (newVal) intervalScroll = setInterval(scroll(), scrollDelay)
  },
  {
    immediate: true
  }
)
</script>

<template>
  <div class="table-container" @mouseover="srollable = false" @mouseout="srollable = true">
    <!-- 多级标头border会被固定为true -->
    <el-table
      ref="tableRef"
      :height="height || 'auto'"
      :style="transparent ? transparentStyle : null"
      :data="tableData"
      row-key="id"
      :border="false"
      stripe
      @selection-change="handleSelectionChange"
    >
      <el-table-column v-if="selection" :type="'selection'" reserve-selection :width="55" />
      <TableColumn v-for="item of tableThArr" :key="item.id" :th-data="item" />
      <el-table-column
        v-if="slots.operations"
        label="操作"
        align="center"
        fixed="right"
        :width="100"
      >
        <template #default="{ row, column }">
          <slot name="operations" :row="row" :column="column" />
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<style scoped>
.table-container {
  box-sizing: border-box;
}
</style>
